// 系统监控和指标收集
import client from 'prom-client';
import config from '../config/config.js';

// 注册指标收集器
const register = new client.Registry();

// 设置默认标签
register.setDefaultLabels({
  app: config.app.name,
  version: config.app.version,
  environment: config.app.environment
});

// 定义指标
const httpRequestDurationMicroseconds = new client.Histogram({
  name: 'http_request_duration_ms',
  help: 'HTTP请求持续时间（毫秒）',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.1, 5, 15, 50, 100, 500, 1000, 5000]
});

const httpRequestsTotal = new client.Counter({
  name: 'http_requests_total',
  help: 'HTTP请求总数',
  labelNames: ['method', 'route', 'status_code']
});

const databaseConnections = new client.Gauge({
  name: 'database_connections',
  help: '数据库连接数',
  labelNames: ['state'] // active, idle, waiting
});

const memoryUsage = new client.Gauge({
  name: 'nodejs_memory_usage_bytes',
  help: 'Node.js内存使用情况',
  labelNames: ['type'] // heap_used, heap_total, external, rss
});

const uptime = new client.Gauge({
  name: 'application_uptime_seconds',
  help: '应用运行时间（秒）'
});

// 注册指标
register.registerMetric(httpRequestDurationMicroseconds);
register.registerMetric(httpRequestsTotal);
register.registerMetric(databaseConnections);
register.registerMetric(memoryUsage);
register.registerMetric(uptime);

// 请求监控中间件
const requestMonitoring = (req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = Date.now() - start;
    const route = req.route?.path || req.path;
    
    httpRequestDurationMicroseconds
      .labels(req.method, route, res.statusCode.toString())
      .observe(duration);
    
    httpRequestsTotal
      .labels(req.method, route, res.statusCode.toString())
      .inc();
  });
  
  next();
};

// 数据库连接监控
const monitorDatabaseConnections = async (dbPool) => {
  try {
    const stats = await dbPool.getPoolStats?.() || {};
    
    databaseConnections.labels('active').set(stats.totalCount || 0);
    databaseConnections.labels('idle').set(stats.idleCount || 0);
    databaseConnections.labels('waiting').set(stats.waitingCount || 0);
  } catch (error) {
    console.warn('无法获取数据库连接统计:', error.message);
  }
};

// 内存使用监控
const monitorMemoryUsage = () => {
  const mem = process.memoryUsage();
  
  memoryUsage.labels('heap_used').set(mem.heapUsed);
  memoryUsage.labels('heap_total').set(mem.heapTotal);
  memoryUsage.labels('external').set(mem.external);
  memoryUsage.labels('rss').set(mem.rss);
};

// 运行时间监控
const monitorUptime = () => {
  uptime.set(process.uptime());
};

// 定期收集指标
const startMetricsCollection = (dbPool) => {
  if (!config.monitoring.enabled) return;
  
  setInterval(() => {
    monitorDatabaseConnections(dbPool);
    monitorMemoryUsage();
    monitorUptime();
  }, 15000); // 每15秒收集一次
};

// 指标端点
const metricsEndpoint = async (req, res) => {
  if (!config.monitoring.enabled) {
    return res.status(404).json({ error: '监控功能未启用' });
  }
  
  try {
    res.set('Content-Type', register.contentType);
    const metrics = await register.metrics();
    res.send(metrics);
  } catch (error) {
    res.status(500).json({ error: '无法获取指标数据' });
  }
};

// 健康检查端点
const healthCheckEndpoint = async (req, res) => {
  const health = {
    status: 'healthy',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    memory: process.memoryUsage(),
    version: config.app.version
  };
  
  // 检查数据库连接
  try {
    if (dbPool) {
      await dbPool.query('SELECT 1');
      health.database = 'connected';
    }
  } catch (error) {
    health.database = 'disconnected';
    health.status = 'degraded';
  }
  
  // 检查Redis连接
  try {
    if (redisClient) {
      await redisClient.ping();
      health.redis = 'connected';
    }
  } catch (error) {
    health.redis = 'disconnected';
    health.status = 'degraded';
  }
  
  res.json(health);
};

export {
  register,
  requestMonitoring,
  startMetricsCollection,
  metricsEndpoint,
  healthCheckEndpoint,
  monitorDatabaseConnections,
  monitorMemoryUsage,
  monitorUptime
};